#include <iostream>
#include <memory>
#include "binary_tree.h"
#include "binary_tree_order.h"

using SharedPtrCharBinaryTree = BinaryTree<char, std::shared_ptr>;

struct PrintBinaryTree {
    void operator() (const SharedPtrCharBinaryTree::Pointer& node) const {
        std::cout << node->value;
    }
};

int main(int , char *[])
{
    std::cout << "Tree structure:\n"
            << "     A\n"
            << "   B   C\n"
            << "  D E   F\n"
            << " G\n";

    SharedPtrCharBinaryTree::Pointer root(new SharedPtrCharBinaryTree('A'));
    root->left.reset(new SharedPtrCharBinaryTree('B'));
    root->left->left.reset(new SharedPtrCharBinaryTree('D'));
    root->left->left->left.reset(new SharedPtrCharBinaryTree('G'));
    root->left->right.reset(new SharedPtrCharBinaryTree('E'));
    root->right.reset(new SharedPtrCharBinaryTree('C'));
    root->right->right.reset(new SharedPtrCharBinaryTree('F'));

    std::cout << "preOrder: "; //ABDGECF
    preOrderTraversal(root, PrintBinaryTree());
    std::cout << std::endl;

    std::cout << "inOrder: "; //GDBEACF
    inOrderTraversal(root, PrintBinaryTree());
    std::cout << std::endl;

    std::cout << "postOrder: "; //GDEBFCA
    postOrderTraversal(root, PrintBinaryTree());
    std::cout << std::endl;

    std::cout << "levelOrder: "; //ABCDEFG
    levelOrderTraversal(root, PrintBinaryTree());
    std::cout << std::endl;

    return 0;
}
